package com.imooc.security.browser;

import com.imooc.security.core.auth.AbstractChannelSecurityConfig;
import com.imooc.security.core.auth.mobile.SmsCodeAuthenticationSecurityConfig;
import com.imooc.security.core.properties.SecurityConstants;
import com.imooc.security.core.properties.SecurityProperties;
import com.imooc.security.core.validate.code.ValidateCodeSecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;

/**
 * @Author sherry
 * @Description
 * @Date Create in 2019-03-16
 * @Modified By:
 */
@Configuration
public class BrowserSecurityConfig extends AbstractChannelSecurityConfig/*WebSecurityConfigurerAdapter*/ {

    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    private ValidateCodeSecurityConfig validateCodeSecurityConfig;
    @Autowired
    private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;


    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    @Autowired
    private DataSource dataSource;

    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        //启动的时候就初始化表，注意，就在第一次启动的时候执行，以后要注释掉
//        tokenRepository.setCreateTableOnStartup(true);
        return tokenRepository;
    }

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        applyPasswordAuthenticationConfig(http);

        http.apply(validateCodeSecurityConfig)
                    .and()
                .apply(smsCodeAuthenticationSecurityConfig)
                    .and()
                .rememberMe()
                    .tokenRepository(persistentTokenRepository())
                    .tokenValiditySeconds(securityProperties.getBrowser().getRememberMeSeconds())
                    .userDetailsService(userDetailsService)
                    .and()
//                配置认证请求方式
                .authorizeRequests()
                //                跳转到登陆页面的请求不需要认证
                    .antMatchers(securityProperties.getBrowser().getLoginPage()
                        , SecurityConstants.DEFAULT_UNAUTHENTICATION_URL
                        , SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_MOBILE
                        , SecurityConstants.DEFAULT_VALIDATE_CODE_URL_PREFIX+"/*").permitAll()
                //                所有的请求
                    .anyRequest()
                //                都需要身份认证
                    .authenticated()
//        忽略CSRF认证，是Spring Boot Security默认配置的一个安全项（跨站请求防护），暂时关闭
                    .and()
                .csrf().disable();
//        设置认证方式

    }
}
